package services

import (
	"gitee.com/kun_liu/to-log/app/models"
	"gitee.com/kun_liu/to-log/pkg/database"
	"gorm.io/gorm"
)

// CommentService 评论服务
type CommentService struct {
	db *gorm.DB
}

// NewCommentService 创建评论服务
func NewCommentService() *CommentService {
	return &CommentService{
		db: database.GetDB(),
	}
}

// GetComments 获取评论列表
func (s *CommentService) GetComments(page, pageSize int) ([]models.Comment, int64, error) {
	var comments []models.Comment
	var total int64

	// 获取总数
	s.db.Model(&models.Comment{}).Count(&total)

	// 获取分页数据
	result := s.db.Order("created DESC").Limit(pageSize).Offset((page - 1) * pageSize).Find(&comments)

	return comments, total, result.Error
}

// GetCommentsByContentID 根据内容ID获取评论
func (s *CommentService) GetCommentsByContentID(contentID uint, page, pageSize int) ([]models.Comment, int64, error) {
	var comments []models.Comment
	var total int64

	// 获取总数
	s.db.Model(&models.Comment{}).Where("cid = ?", contentID).Count(&total)

	// 获取分页数据
	result := s.db.Where("cid = ? AND parent = 0", contentID).Order("created ASC").Limit(pageSize).Offset((page - 1) * pageSize).Find(&comments)
	if result.Error != nil {
		return nil, 0, result.Error
	}

	// 获取子评论
	for i := range comments {
		err := s.getChildComments(&comments[i])
		if err != nil {
			return nil, 0, err
		}
	}

	return comments, total, nil
}

// getChildComments 递归获取子评论
func (s *CommentService) getChildComments(comment *models.Comment) error {
	var children []models.Comment
	result := s.db.Where("parent = ?", comment.ID).Order("created ASC").Find(&children)
	if result.Error != nil {
		return result.Error
	}

	comment.Children = children

	// 递归获取子评论的子评论
	for i := range children {
		err := s.getChildComments(&children[i])
		if err != nil {
			return err
		}
	}

	return nil
}

// GetCommentByID 根据ID获取评论
func (s *CommentService) GetCommentByID(id uint) (models.Comment, error) {
	var comment models.Comment
	result := s.db.First(&comment, id)
	return comment, result.Error
}

// CreateComment 创建评论
func (s *CommentService) CreateComment(comment *models.Comment) error {
	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建评论
	if err := tx.Create(comment).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新文章评论数
	var post models.Post
	if err := tx.First(&post, comment.CID).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 增加评论数
	post.CommentsNum++
	if err := tx.Save(&post).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 提交事务
	return tx.Commit().Error
}

// UpdateComment 更新评论
func (s *CommentService) UpdateComment(comment *models.Comment) error {
	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 更新评论
	if err := tx.Save(comment).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 提交事务
	return tx.Commit().Error
}

// DeleteComment 删除评论
func (s *CommentService) DeleteComment(id uint) error {
	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 获取评论
	var comment models.Comment
	if err := tx.First(&comment, id).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 检查是否有子评论
	var childCount int64
	if err := tx.Model(&models.Comment{}).Where("parent = ?", id).Count(&childCount).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 如果有子评论，则将评论状态设置为已删除，而不是真正删除
	if childCount > 0 {
		comment.Status = "deleted"
		if err := tx.Save(&comment).Error; err != nil {
			tx.Rollback()
			return err
		}
	} else {
		// 否则直接删除评论
		if err := tx.Delete(&comment).Error; err != nil {
			tx.Rollback()
			return err
		}
	}

	// 更新文章评论数
	var post models.Post
	if err := tx.First(&post, comment.CID).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 减少评论数
	if post.CommentsNum > 0 {
		post.CommentsNum--
		if err := tx.Save(&post).Error; err != nil {
			tx.Rollback()
			return err
		}
	}

	// 提交事务
	return tx.Commit().Error
}

// ApproveComment 审核评论
func (s *CommentService) ApproveComment(id uint) error {
	return s.db.Model(&models.Comment{}).Where("coid = ?", id).Update("status", "approved").Error
}

// SpamComment 标记评论为垃圾
func (s *CommentService) SpamComment(id uint) error {
	return s.db.Model(&models.Comment{}).Where("coid = ?", id).Update("status", "spam").Error
}
